package org.andes.kownledge.operator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.andes.base.Bindings;
import org.andes.base.auxiliary;
import org.andes.kownledge.operator.func.Func;

public class Predication extends NoAtom  {
	private String predicate;
	private List<Term> arguments=new ArrayList<Term>();
	
	public String getPredicate() {
		return predicate;
	}
	public void setPredicate(String predicate) {
		this.predicate = predicate;
	}
	public List<Term> getArguments() {
		return arguments;
	}
	public void setArguments(List<Term> arguments) {
		this.arguments = arguments;
	}
	public void addArgument(Term term){
		arguments.add(term);		
	}
	protected Map<String,Term> keys=new HashMap<String,Term>();
	public void addKey(Key key){
		keys.put(key.getType(), key.getValue());
	}
	public List<String> getKeys(){
		List<String> result=new ArrayList<String>();
		result.addAll(keys.keySet());
		return result;
	}
	public Term getKeyValue(String key){
		return keys.get(key);
	}
	
	public String toString(){
		StringBuffer sb=new StringBuffer();
		sb.append("("+predicate);
		sb.append(" ");
		for(Term term:arguments){
			sb.append(term.toString());
			sb.append(" ");
		}
		sb.append(")");
		return sb.toString();
	}
	@Override
	public Term substBindings(Bindings bindings) {
		Predication result;
		try {
			result = this.getClass().newInstance();
			result.setPredicate(getPredicate());
			for(Term term:arguments){
				Term term1=term.substBindings(bindings);
				result.addArgument(term1);
			}
			for(String key:keys.keySet()){
				Term term1=keys.get(key).substBindings(bindings);
				result.addKey(new Key(key,term1));
			}
			return result;
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	@Override
	public Predication renameVariable() {
		Predication result=new Predication();
		result.setPredicate(getPredicate());
		for(Term term:getArguments()){
			Term term2=term.renameVariable();
			result.addArgument(term2);						
		}
		for(String keyname:keys.keySet()){
			Term term2=keys.get(keyname).renameVariable();
			Key key=new Key(keyname);
			key.setValue(term2);
			result.addKey(key);
		}
		
		return result;
	}
	@Override
	public List<Variable> getVars() {
		List<Variable> result=new ArrayList<Variable>();
		for(Term term:arguments){
			if(term instanceof NoAtom){
				result.addAll(((NoAtom)term).getVars());
			}else if(term instanceof Variable)
				result.add((Variable) term);
				
		}
		return result;
	}
}
